home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / net_src.arc / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-08  |  26.9 KB  |  1,244 lines

  1. /* Main network program - provides both client and server functions */
  2.  
  3.  
  4. #define HOSTNAMELEN 64
  5. unsigned restricted_dev=1000;
  6. extern char *startup;    /* File to read startup commands from */
  7. #include <stdio.h>
  8. #include "config.h"
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "netuser.h"
  12. #include "timer.h"
  13. #include "icmp.h"
  14. #include "iface.h"
  15. #include "ip.h"
  16. #include "tcp.h"
  17. #include "ax25.h"
  18. #include "netrom.h"
  19. #include "ftp.h"
  20. #include "telnet.h"
  21. #include "remote.h"
  22. #include "session.h"
  23. #include "cmdparse.h"
  24.  
  25. #ifdef    ASY
  26. #include "asy.h"
  27. #include "slip.h"
  28. #endif
  29.  
  30. #ifdef    NRS
  31. #include "nrs.h"
  32. #endif
  33.  
  34. #ifdef    SLFP
  35. #include "slfp.h"
  36. #endif
  37.  
  38. #ifdef UNIX        /* BSD or SYS5 */
  39. #include "unix.h"
  40. #endif
  41.  
  42. #ifdef AMIGA
  43. #include "amiga.h"
  44. #endif
  45.  
  46. #ifdef MAC
  47. #include "mac.h"
  48. #endif
  49.  
  50. #ifdef MSDOS
  51. #include "asy.h"
  52. #endif
  53.  
  54. #ifdef    ATARI_ST
  55. #include "st.h"
  56.  
  57. #ifdef    LATTICE
  58. long _MNEED = 100000L;        /* Reserve RAM for subshell... */
  59. long _32K = 0x8000;        /* For GST Linker (Don't ask me! -- hyc) */
  60. #endif
  61.  
  62. #ifdef    MWC
  63. long    _stksize = 16384L;    /* Fixed stack size... -- hyc */
  64. #endif
  65. #endif    /* ATARI_ST */
  66.  
  67. #ifdef    SYS5
  68. #include <signal.h>
  69. int    background = 0;
  70. #endif
  71.  
  72. #ifdef    TRACE
  73. #include "trace.h"
  74. /* Dummy structure for loopback tracing */
  75. struct interface loopback = { NULLIF, "loopback" };
  76. #endif
  77.  
  78. extern struct interface *ifaces;
  79. extern char version[];
  80. extern struct mbuf *loopq;
  81. extern FILE *trfp;
  82. extern char trname[];
  83.  
  84. int mode;
  85. FILE *logfp;
  86. char badhost[] = "Unknown host %s\n";
  87. char hostname[HOSTNAMELEN];    
  88. unsigned nsessions = NSESSIONS;
  89. int32 resolve();
  90. int16 lport = 1001;
  91. char prompt[] = "net> ";
  92. char nospace[] = "No space!!\n";    /* Generic malloc fail message */
  93. #ifdef    SYS5
  94. int io_active = 0;
  95. #endif
  96.  
  97. #if ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))    /* PC/ST uses F-10 key always */
  98. static char escape = 0x1d;    /* default escape character is ^] */
  99. #endif
  100.  
  101. /* Command lookup and branch table */
  102. int go(),doax25(),cmdmode(),doconnect(),dotelnet(),doexit(),doclose(),
  103.     dohostname(),doreset(),dotcp(),dotrace(),doescape(),dohelp(),
  104.     doroute(),doecho(),dolog(),doip(),
  105.     memstat(),doarp(),dosession(),doftp(),dostart(),dostop(),doattach(),
  106.     dosmtp(),doudp(),doparam(),doeol(),
  107.     dodump(),dorecord(),doupload(),dokick(),domode(),doshell(),
  108.     dodir(),docd(),doatstat(),doping(),doforward(),doremote(),donetrom(),
  109.     donrstat(), dombox(), mulport() ;
  110.  
  111. #ifdef ETHER
  112. int doetherstat();
  113. #endif
  114. #ifdef EAGLE
  115. int doegstat();
  116. #endif
  117. #ifdef HAPN
  118. int dohapnstat();
  119. #endif
  120. #ifdef _FINGER
  121. int dofinger();
  122. #endif
  123.  
  124. static struct cmds cmds[] = {
  125.     /* The "go" command must be first */
  126.     "",        go,        0, NULLCHAR,    NULLCHAR,
  127.     "!",        doshell,    0, NULLCHAR,    NULLCHAR,
  128. #if    (MAC && APPLETALK)
  129.     "applestat",    doatstat,    0,    NULLCHAR,    NULLCHAR,
  130. #endif
  131. #if    (AX25 || ETHER || APPLETALK)
  132.     "arp",        doarp,        0, NULLCHAR,    NULLCHAR,
  133. #endif
  134. #ifdef    AX25
  135.     "ax25",        doax25,        0, NULLCHAR,    NULLCHAR,
  136. #endif    
  137.     "attach",    doattach,    2,
  138.         "attach <hardware> <hw specific options>", NULLCHAR,
  139. /* This one is out of alpabetical order to allow abbreviation to "c" */
  140. #ifdef    AX25
  141.     "connect",    doconnect,    3,"connect <interface> <callsign> [digipeaters]",
  142.         NULLCHAR,
  143. #endif
  144. #ifndef UNIX    /* BSD or SYS5 */
  145.     "cd",        docd,        0, NULLCHAR,    NULLCHAR,
  146. #endif
  147.     "close",    doclose,    0, NULLCHAR,    NULLCHAR,
  148.     "disconnect",    doclose,    0, NULLCHAR,    NULLCHAR,
  149.     "dir",        dodir,        0, NULLCHAR,    NULLCHAR,
  150. #ifdef    EAGLE
  151.     "eaglestat",    doegstat,    0, NULLCHAR,    NULLCHAR,
  152. #endif
  153.     "echo",        doecho,        0, NULLCHAR,    "echo [refuse|accept]",
  154.     "eol",        doeol,        0, NULLCHAR,
  155.         "eol options: unix, standard",
  156. #if    ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
  157.     "escape",    doescape,    0, NULLCHAR,    NULLCHAR,   
  158. #endif
  159. #ifdef    PC_EC
  160.     "etherstat",    doetherstat,    0, NULLCHAR,    NULLCHAR,
  161. #endif  PC_EC
  162.     "exit",        doexit,        0, NULLCHAR,    NULLCHAR,
  163. #ifdef _FINGER
  164.     "finger",    dofinger,    0, NULLCHAR, NULLCHAR,
  165. #endif
  166.     "forward",    doforward,    0, NULLCHAR,    NULLCHAR,
  167.     "ftp",        doftp,        2, "ftp <address>",    NULLCHAR,
  168. #ifdef HAPN
  169.     "hapnstat",    dohapnstat,    0, NULLCHAR,    NULLCHAR,
  170. #endif
  171.     "help",        dohelp,        0, NULLCHAR,    NULLCHAR,
  172.     "hostname",    dohostname,    0, NULLCHAR,    NULLCHAR,
  173.     "kick",        dokick,        0, NULLCHAR,    NULLCHAR,
  174.     "log",        dolog,        0, NULLCHAR,    NULLCHAR,
  175.     "ip",        doip,        0, NULLCHAR,    NULLCHAR,
  176.     "memstat",    memstat,    0, NULLCHAR,    NULLCHAR,
  177. #ifdef    AX25
  178.     "mbox",        dombox,        0, NULLCHAR,    NULLCHAR,
  179.     "mode",        domode,        2, "mode <interface>",    NULLCHAR,
  180. #endif
  181. #ifdef    MULPORT
  182.     "mulport",    mulport,    2, "mulport <on|off>",    NULLCHAR,
  183. #endif
  184. #ifdef    NETROM
  185.     "netrom",    donetrom,    0, NULLCHAR,    NULLCHAR,
  186. #ifdef    NRS
  187.     "nrstat",    donrstat,    0, NULLCHAR,    NULLCHAR,
  188. #endif
  189. #endif
  190.     "param",    doparam,    2, "param <interface>", NULLCHAR,
  191.     "ping",        doping,        0, NULLCHAR,    NULLCHAR,
  192. #ifndef UNIX /* BSD or SYS5 */
  193.     "pwd",        docd,        0, NULLCHAR,    NULLCHAR,
  194. #endif
  195.     "record",    dorecord,    0, NULLCHAR,    NULLCHAR,
  196.     "remote",    doremote,    4, "remote <address> <port> <command>",
  197.                             NULLCHAR,
  198.     "reset",    doreset,    0, NULLCHAR,    NULLCHAR,
  199.     "route",    doroute,    0, NULLCHAR,    NULLCHAR,
  200.     "session",    dosession,    0, NULLCHAR,    NULLCHAR,
  201.     "shell",    doshell,    0, NULLCHAR,    NULLCHAR,
  202.     "smtp",        dosmtp,        0, NULLCHAR,    NULLCHAR,
  203. #ifdef    SERVERS
  204.     "start",    dostart,    2, "start <servername>",NULLCHAR,
  205.     "stop",        dostop,        2, "stop <servername>",    NULLCHAR,
  206. #endif
  207.     "tcp",        dotcp,        0, NULLCHAR,    NULLCHAR,
  208.     "telnet",    dotelnet,    2, "telnet <address>",    NULLCHAR,
  209. #ifdef    TRACE
  210.     "trace",    dotrace,    0, NULLCHAR,    NULLCHAR,
  211. #endif
  212.     "udp",        doudp,        0, NULLCHAR,    NULLCHAR,
  213.     "upload",    doupload,    0, NULLCHAR,    NULLCHAR,
  214.     "?",        dohelp,        0, NULLCHAR,    NULLCHAR,
  215.     NULLCHAR,    NULLFP,        0,
  216.         "Unknown command; type \"?\" for list",   NULLCHAR, 
  217. };
  218.  
  219. #ifdef    SERVERS
  220. /* "start" and "stop" subcommands */
  221. int dis1(),echo1(),ftp1(),smtp1(),tn1(),rem1();
  222.  
  223. #ifdef UNIX
  224. int tnix1();
  225. #endif
  226.  
  227. #ifdef _FINGER
  228. int finger1();
  229. #endif
  230.  
  231. static struct cmds startcmds[] = {
  232.     "discard",    dis1,        0, NULLCHAR, NULLCHAR,
  233.     "echo",        echo1,        0, NULLCHAR, NULLCHAR,
  234. #ifdef _FINGER
  235.     "finger",    finger1,    0, NULLCHAR, NULLCHAR,
  236. #endif
  237.     "ftp",        ftp1,        0, NULLCHAR, NULLCHAR,
  238.     "smtp",        smtp1,        0, NULLCHAR, NULLCHAR,
  239.     "telnet",    tn1,        0, NULLCHAR, NULLCHAR,
  240. #ifdef    UNIX
  241.     "telunix",    tnix1,        0, NULLCHAR, NULLCHAR,
  242. #endif
  243.     "remote",    rem1,        0, NULLCHAR, NULLCHAR,
  244.     NULLCHAR,    NULLFP,        0,
  245. #ifdef UNIX
  246. #ifdef _FINGER
  247.         "start options: discard, echo, finger, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  248. #else
  249.         "start options: discard, echo, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  250. #endif
  251. #else /* UNIX */
  252. #ifdef _FINGER
  253.         "start options: discard, echo, finger, ftp, remote, smtp, telnet", NULLCHAR,
  254. #else
  255.         "start options: discard, echo, ftp, remote, smtp, telnet", NULLCHAR,
  256. #endif
  257. #endif /* UNIX */
  258. };
  259. int ftp_stop(),smtp_stop(),echo_stop(),dis_stop(),tn_stop();
  260. int dis0(),echo0(),ftp0(),smtp0(),tn0(),rem0();
  261.  
  262. #ifdef UNIX
  263. int tnix0();
  264. #endif
  265.  
  266. #ifdef _FINGER
  267. int finger0();
  268. #endif
  269.  
  270. static struct cmds stopcmds[] = {
  271.     "discard",    dis0,        0, NULLCHAR, NULLCHAR,
  272.     "echo",        echo0,        0, NULLCHAR, NULLCHAR,
  273. #ifdef _FINGER
  274.     "finger",    finger0,    0, NULLCHAR, NULLCHAR,
  275. #endif
  276.     "ftp",        ftp0,        0, NULLCHAR, NULLCHAR,
  277.     "smtp",        smtp0,        0, NULLCHAR, NULLCHAR,
  278.     "telnet",    tn0,        0, NULLCHAR, NULLCHAR,
  279. #ifdef UNIX
  280.     "telunix",    tnix0,        0, NULLCHAR, NULLCHAR,
  281. #endif
  282.     "remote",    rem0,        0, NULLCHAR, NULLCHAR,
  283.     NULLCHAR,    NULLFP,        0,
  284. #ifdef UNIX
  285. #ifdef _FINGER
  286.         "stop options: discard, echo, finger, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  287. #else
  288.         "stop options: discard, echo, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  289. #endif
  290. #else /* UNIX */
  291. #ifdef _FINGER
  292.         "stop options: discard, echo, finger, ftp, remote, smtp, telnet", NULLCHAR,
  293. #else
  294.         "stop options: discard, echo, ftp, remote, smtp, telnet", NULLCHAR,
  295. #endif
  296. #endif /* UNIX */
  297. };
  298. #endif
  299.  
  300. void
  301. keep_things_going()
  302. {
  303.     void check_time(), ip_recv();
  304.     struct interface *ifp;
  305.     struct mbuf *bp;
  306.  
  307.     /* Service the loopback queue */
  308.     if((bp = dequeue(&loopq)) != NULLBUF){
  309.         struct ip ip;
  310. #ifdef    TRACE
  311.         dump(&loopback,IF_TRACE_IN,TRACE_IP,bp);        
  312. #endif
  313.         /* Extract IP header */
  314.         ntohip(&ip,&bp);
  315.         ip_recv(&ip,bp,0);
  316.     }
  317.     /* Service the interfaces */
  318. #ifdef    SYS5
  319.     do {
  320.     io_active = 0;
  321. #endif
  322.     for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next){
  323.         if(ifp->recv != NULLVFP)
  324.             (*ifp->recv)(ifp);
  325.     }
  326. #ifdef    SYS5
  327.     } while(io_active);
  328. #endif
  329.  
  330. #ifdef    XOBBS
  331.     /* service the W2XO PBBS code */
  332.     axchk();
  333. #endif
  334.  
  335.  
  336.  
  337.     /* Service the clock if it has ticked */
  338.     check_time();
  339.  
  340. #ifdef    MSDOS
  341.     /* Tell DoubleDos to let the other task run for awhile.
  342.      * If DoubleDos isn't active, this is a no-op
  343.      */
  344. #ifndef PLUS
  345.     giveup();
  346. #endif
  347. #else
  348.     /* Wait until interrupt, then do it all over again */
  349.     eihalt();
  350. #endif
  351. }
  352.  
  353. main(argc,argv)
  354. int argc;
  355. char *argv[];
  356. {
  357.     static char inbuf[BUFSIZ];    /* keep it off the stack */
  358.     int c;
  359.     char *ttybuf,*fgets();
  360.     int16 cnt;
  361.     int ttydriv();
  362.     int cmdparse();
  363.     void check_time(),ip_recv();
  364.     FILE *fp;
  365.     struct interface *ifp;
  366.     struct mbuf *bp;
  367. #ifdef    UNIX
  368.     char *p;
  369.     static char startfn[256];
  370.     char *getenv();
  371. #endif
  372. #ifdef    FLOW
  373.     extern int ttyflow;
  374. #endif
  375. #ifdef    SYS5
  376.     if (signal(SIGINT, SIG_IGN) == SIG_IGN) {
  377.         background++;
  378.         daemon();
  379.     } else
  380.         ioinit();
  381. #else
  382.     ioinit();
  383. #endif
  384.  
  385. #ifdef PLUS
  386. /*
  387.  * set: cursor to block, attributes off, keyboard to ALT mode, 
  388.  *      transmit functions off, use HP fonts
  389.  */
  390.     printf(   "\033&d@"     /* display attributes off         */
  391.                   "\033[11m");  /* use ALT fonts                  */
  392. #endif
  393. #ifdef    MSDOS
  394. #ifndef PLUS
  395.     chktasker();
  396. #endif
  397. #endif
  398. #ifdef    MSDOS
  399.     printf("KA9Q Internet Protocol Package, v%s DS = %x\n",version,
  400.         getds());
  401. #else
  402. #ifdef    SYS5
  403.     if (!background) {
  404. #endif
  405.         printf("KA9Q Internet Protocol Package, v%s\n",version);
  406. #endif
  407.         printf("Copyright 1988 by Phil Karn, KA9Q\n");
  408. #ifdef NETROM
  409.         printf("NET/ROM Support Copyright 1989 by Dan Frank, W9NK\n") ;
  410. #endif
  411. #ifdef    SYS5
  412.     }
  413. #endif
  414.     fflush(stdout);
  415.     sessions = (struct session *)calloc(nsessions,sizeof(struct session));
  416.     if(argc > 1){
  417.         /* Read startup file named on command line */
  418.         fp = fopen(argv[1],"r");
  419.     } else {
  420.         fp = fopen(startup,"r");
  421.     }
  422.     if(fp != NULLFILE){
  423.         while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
  424.             cmdparse(cmds,inbuf);
  425.         }
  426.         fclose(fp);
  427.     }        
  428. #ifdef XOBBS
  429.     axinit();
  430. #endif
  431.     cmdmode();
  432.  
  433.     /* Main commutator loop */
  434.     for(;;){
  435.         /* Process any keyboard input */
  436. #ifdef    SYS5
  437.         while((background == 0) && ((c = kbread()) != -1)){
  438. #else
  439.         while((c = kbread()) != -1){
  440. #endif
  441. #if    (defined(MSDOS) || defined(ATARI_ST))
  442.             /* c == -2 means the command escape key (F10) */
  443.             if(c == -2){
  444.                 if(mode != CMD_MODE){
  445.                     printf("\n");
  446.                     cmdmode();
  447.                 }
  448.                 continue;
  449.             }
  450. #endif
  451. #ifdef SYS5
  452.             if(c == escape && escape != 0){
  453.                 if(mode != CMD_MODE){
  454.                     printf("\r\n");
  455.                     cmdmode();
  456.                 }
  457.                 continue;
  458.             }
  459. #endif     /* SYS5 */
  460.  
  461. #ifndef    FLOW
  462.             if ((cnt = ttydriv(c, &ttybuf)) == 0)
  463.                 continue;
  464. #else
  465.             cnt = ttydriv(c, &ttybuf);
  466.             if (ttyflow && (mode != CMD_MODE))
  467.                 go();        /* display pending chars */
  468.             if (cnt == 0)
  469.                 continue;
  470. #endif    /* FLOW */
  471. #if    (!defined(MSDOS) && !defined(ATARI_ST))
  472.             if((ttybuf[0] == escape) && (escape != 0)) {
  473.                 if(mode != CMD_MODE){
  474.                     printf("\r\n");
  475.                     cmdmode();
  476.                 }
  477.                 continue;
  478.             }
  479. #endif
  480.             switch(mode){
  481.             case CMD_MODE:
  482.                 (void)cmdparse(cmds,ttybuf);
  483.                 fflush(stdout);
  484.                 break;
  485.             case CONV_MODE:
  486. #if    ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
  487.                 if(ttybuf[0] == escape && escape != 0){
  488.                     printf("\n");
  489.                     cmdmode();
  490.                 } else
  491. #endif    /* MSDOS */
  492.                     if(current->parse != NULLFP)
  493.                         (*current->parse)(ttybuf,cnt);
  494.                 break;
  495.             }
  496.             if(mode == CMD_MODE){
  497.                 printf(prompt);
  498.                 fflush(stdout);
  499.             }
  500.         }
  501.         keep_things_going();
  502.     }
  503. }
  504. /* Standard commands called from main */
  505.  
  506. /* Enter command mode */
  507. int
  508. cmdmode()
  509. {
  510.     if(mode != CMD_MODE){
  511.         mode = CMD_MODE;
  512.         cooked();
  513.         printf(prompt);
  514.         fflush(stdout);
  515.     }
  516.     return 0;
  517. }
  518. static
  519. doexit()
  520. {
  521. #if    defined(PLUS)
  522. /*
  523.  * set: cursor to block, attributes off, keyboard to HP mode,
  524.  *      transmit functions off, use HP fonts
  525.  */
  526.     printf(/* "\033*dK"       cursor to block        */
  527.               "\033&d@"    /* display attributes off      */
  528.            /* "\033&k0\\"       KBD to HP mode        */
  529.            /* "\033&s0A"       transmit functions off    */
  530.               "\033[10m");    /* use HP fonts            */
  531. #endif
  532.     if(logfp != NULLFILE)
  533.         fclose(logfp);
  534. #ifdef    SYS5
  535.     if (!background)
  536.         iostop();
  537. #else
  538.     iostop();
  539. #endif
  540. #ifdef TRACE
  541.     if (trfp != stdout) 
  542.       fclose(trfp);
  543. #endif
  544.     exit(0);
  545. }
  546. static
  547. dohostname(argc,argv)
  548. int argc;
  549. char *argv[];
  550. {
  551.     char *strncpy();
  552.  
  553.     if(argc < 2)
  554.         printf("%s\n",hostname);
  555.     else 
  556.         strncpy(hostname,argv[1],HOSTNAMELEN);
  557.     return 0;
  558. }
  559. static
  560. int
  561. dolog(argc,argv)
  562. int argc;
  563. char *argv[];
  564. {
  565.     char *strncpy();
  566.  
  567. #ifdef    UNIX
  568.     static char logname[256];
  569. #else
  570.     static char logname[15];
  571. #endif
  572.     if(argc < 2){
  573.         if(logfp)
  574.             printf("Logging to %s\n",logname);
  575.         else
  576.             printf("Logging off\n");
  577.         return 0;
  578.     }
  579.     if(logfp){
  580.         fclose(logfp);
  581.         logfp = NULLFILE;
  582.     }
  583.     if(strcmp(argv[1],"stop") != 0){
  584. #ifdef    UNIX
  585.         strncpy(logname,argv[1],sizeof(logname));
  586. #else
  587.         strncpy(logname,argv[1],15);
  588. #endif
  589.         logfp = fopen(logname,"a+");
  590.     }
  591.     return 0;
  592. }
  593. static
  594. int
  595. dohelp()
  596. {
  597.     register struct cmds *cmdp;
  598.     int i,j;
  599.  
  600.     printf("Main commands:\n");
  601.     for(i=0,cmdp = cmds;cmdp->name != NULL;cmdp++,i++){
  602.         printf("%s",cmdp->name);
  603.         if((i % 4) == 3)
  604.             printf("\n");
  605.         else {
  606.             for(j=strlen(cmdp->name);j < 16; j++)
  607.                 putchar(' ');
  608.         }
  609.     }
  610.     if((i % 4) != 0)
  611.         printf("\n");
  612.     return 0;
  613. }
  614.  
  615. doecho(argc,argv)
  616. int argc;
  617. char *argv[];
  618. {
  619.     extern int refuse_echo;
  620.  
  621.     if(argc < 2){
  622.         if(refuse_echo)
  623.             printf("Refuse\n");
  624.         else
  625.             printf("Accept\n");
  626.     } else {
  627.         if(argv[1][0] == 'r')
  628.             refuse_echo = 1;
  629.         else if(argv[1][0] == 'a')
  630.             refuse_echo = 0;
  631.         else
  632.             return -1;
  633.     }
  634.     return 0;
  635. }
  636. /* set for unix end of line for remote echo mode telnet */
  637. doeol(argc,argv)
  638. int argc;
  639. char *argv[];
  640. {
  641.     extern int unix_line_mode;
  642.  
  643.     if(argc < 2){
  644.         if(unix_line_mode)
  645.             printf("Unix\n");
  646.         else
  647.             printf("Standard\n");
  648.     } else {
  649.         if(strcmp(argv[1],"unix") == 0)
  650.             unix_line_mode = 1;
  651.         else if(strcmp(argv[1],"standard") == 0)
  652.             unix_line_mode = 0;
  653.         else {
  654.             return -1;
  655.         }
  656.     }
  657.     return 0;
  658. }
  659. /* Attach an interface
  660.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  661.  */
  662. doattach(argc,argv)
  663. int argc;
  664. char *argv[];
  665. {
  666.     extern struct cmds attab[];
  667.  
  668.     return subcmd(attab,argc,argv);
  669. }
  670. /* Manipulate I/O device parameters */
  671. doparam(argc,argv)
  672. int argc;
  673. char *argv[];
  674. {
  675.     register struct interface *ifp;
  676.  
  677.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  678.         if(strcmp(argv[1],ifp->name) == 0)
  679.             break;
  680.     }
  681.     if(ifp == NULLIF){
  682.         printf("Interface \"%s\" unknown\n",argv[1]);
  683.         return 1;
  684.     }
  685.     if(ifp->ioctl == NULLFP){
  686.         printf("Not supported\n");
  687.         return 1;
  688.     }
  689.     /* Pass rest of args to device-specific code */
  690.     return (*ifp->ioctl)(ifp,argc-2,argv+2);
  691. }
  692. /* Log messages of the form
  693.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  694.  */
  695. /*VARARGS2*/
  696. log(tcb,fmt,arg1,arg2,arg3,arg4)
  697. struct tcb *tcb;
  698. char *fmt;
  699. int arg1,arg2,arg3,arg4;
  700. {
  701.     char *cp;
  702.     long t;
  703.     int fd;
  704.  
  705.     if(logfp == NULLFILE)
  706.         return;
  707.     time(&t);
  708.     cp = ctime(&t);
  709.     rip(cp);
  710.     fprintf(logfp,"%s %s - ",cp,psocket(&tcb->conn.remote));
  711.     fprintf(logfp,fmt,arg1,arg2,arg3,arg4);
  712.     fprintf(logfp,"\n");
  713.     fflush(logfp);
  714. #if    (defined(MSDOS) || defined(ATARI_ST))
  715.     /* MS-DOS doesn't really flush files until they're closed */
  716.     fd = fileno(logfp);
  717.     if((fd = dup(fd)) != -1)
  718.         close(fd);
  719. #endif
  720. }
  721. /* Configuration-dependent code */
  722.  
  723. /* List of supported hardware devices */
  724. int modem_init(),asy_attach(),pc_attach(),at_attach(),nr_attach();
  725.  
  726. #ifdef    EAGLE
  727. int eg_attach();
  728. #endif
  729. #ifdef    HAPN
  730. int hapn_attach();
  731. #endif
  732. #ifdef    PC_EC
  733. int ec_attach();
  734. #endif
  735. #ifdef    PACKET
  736. int pk_attach();
  737. #endif
  738.  
  739. struct cmds attab[] = {
  740. #ifdef    PC_EC
  741.     /* 3-Com Ethernet interface */
  742.     "3c500", ec_attach, 7, 
  743.     "attach 3c500 <address> <vector> arpa <label> <buffers> <mtu>",
  744.     "Could not attach 3c500",
  745. #endif
  746. #ifdef    ASY
  747.     /* Ordinary PC asynchronous adaptor */
  748.     "asy", asy_attach, 8, 
  749. #ifdef    UNIX
  750. #ifndef    SLFP
  751.     "attach asy 0 <ttyname> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
  752. #else
  753.     "attach asy 0 <ttyname> slip|ax25|nrs|slfp <label> <buffers> <mtu> <speed>",
  754. #endif    /* SLFP */
  755. #else
  756. #ifndef    SLFP
  757.     "attach asy <address> <vector> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
  758. #else
  759.     "attach asy <address> <vector> slip|ax25|nrs|slfp <label> <buffers> <mtu> <speed>",
  760. #endif    /* SLFP */
  761. #endif
  762.     "Could not attach asy",
  763. #endif
  764. #ifdef    PC100
  765.     /* PACCOMM PC-100 8530 HDLC adaptor */
  766.     "pc100", pc_attach, 8, 
  767.     "attach pc100 <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  768.     "Could not attach pc100",
  769. #endif
  770. #ifdef    EAGLE
  771.     /* EAGLE RS-232C 8530 HDLC adaptor */
  772.     "eagle", eg_attach, 8,
  773.     "attach eagle <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  774.     "Could not attach eagle",
  775. #endif
  776. #ifdef    HAPN
  777.     /* Hamilton Area Packet Radio (HAPN) 8273 HDLC adaptor */
  778.     "hapn", hapn_attach, 8,
  779.     "attach hapn <address> <vector> ax25 <label> <rx bufsize> <mtu> csma|full",
  780.     "Could not attach hapn",
  781. #endif
  782. #ifdef    APPLETALK
  783.     /* Macintosh AppleTalk */
  784.     "0", at_attach, 7,
  785.     "attach 0 <protocol type> <device> arpa <label> <rx bufsize> <mtu>",
  786.     "Could not attach Appletalk",
  787. #endif
  788. #ifdef NETROM
  789.     /* fake netrom interface */
  790.     "netrom", nr_attach, 1,
  791.     "attach netrom",
  792.     "Could not attach netrom",
  793. #endif
  794. #ifdef    PACKET
  795.     /* FTP Software's packet driver spec */
  796.     "packet", pk_attach, 4,
  797.     "attach packet <int#> <label> <buffers> <mtu>",
  798.     "Could not attach packet driver",
  799. #endif
  800.     NULLCHAR, NULLFP, 0,
  801.     "Unknown device",
  802.     NULLCHAR,
  803. };
  804.  
  805. /* Protocol tracing function pointers */
  806. #ifdef    TRACE
  807. int ax25_dump(),ether_dump(),ip_dump(),at_dump(),slfp_dump();
  808.  
  809. int (*tracef[])() = {
  810. #ifdef    AX25
  811.     ax25_dump,
  812. #else
  813.     NULLFP,
  814. #endif
  815.  
  816. #ifdef    ETHER
  817.     ether_dump,
  818. #else
  819.     NULLFP,
  820. #endif
  821.     ip_dump,
  822.  
  823. #ifdef    APPLETALK
  824.     at_dump,
  825. #else
  826.     NULLFP,
  827. #endif
  828.  
  829. #ifdef    SLFP
  830.     slfp_dump,
  831. #else
  832.     NULLFP,
  833. #endif
  834. };
  835. #else
  836. int (*tracef[])() = { NULLFP };    /* No tracing at all */
  837. dump(interface,direction,type,bp)
  838. struct interface *interface;
  839. int direction;
  840. unsigned type;
  841. struct mbuf *bp;
  842. {
  843. }
  844. #endif
  845.  
  846. #ifdef    ASY
  847.  
  848. /* Attach a serial interface to the system
  849.  * argv[0]: hardware type, must be "asy"
  850.  * argv[1]: I/O address, e.g., "0x3f8"
  851.  * argv[2]: vector, e.g., "4"
  852.  * argv[3]: mode, may be:
  853.  *        "slip" (point-to-point SLIP)
  854.  *        "ax25" (AX.25 frame format in SLIP for raw TNC)
  855.  *        "nrs" (NET/ROM format serial protocol)
  856.  *        "slfp" (point-to-point SLFP, as used by the Merit Network and MIT
  857.  * argv[4]: interface label, e.g., "sl0"
  858.  * argv[5]: receiver ring buffer size in bytes
  859.  * argv[6]: maximum transmission unit, bytes
  860.  * argv[7]: interface speed, e.g, "9600"
  861.  * argv[8]: optional ax.25 callsign (NRS only)
  862.  *        optional command string for modem (SLFP only)
  863.  *          optional modem L.sys style command (SLIP only)
  864.  */
  865. int
  866. asy_attach(argc,argv)
  867. int argc;
  868. char *argv[];
  869. {
  870.     register struct interface *if_asy;
  871.     extern struct interface *ifaces;
  872.     int16 dev;
  873.     int mode;
  874.     int asy_init();
  875.     int asy_send();
  876.     int asy_ioctl();
  877.     void doslip();
  878.     int asy_stop();
  879.     int ax_send();
  880.     int ax_output();
  881.     void kiss_recv();
  882.     int kiss_raw();
  883.     int kiss_ioctl();
  884.     int slip_send();
  885.     void slip_recv();
  886.     int slip_raw();
  887.  
  888. #ifdef    SLFP
  889.     int doslfp();
  890.     int slfp_raw();
  891.     int slfp_send();
  892.     int slfp_recv();
  893.     int slfp_init();
  894. #endif
  895.  
  896. #ifdef    AX25
  897.     struct ax25_addr addr ;
  898. #endif
  899.     int ax_send(),ax_output(),nrs_raw(),asy_ioctl();
  900.     void nrs_recv();
  901.  
  902.     if(nasy >= ASY_MAX){
  903.         printf("Too many asynch controllers\n");
  904.         return -1;
  905.     }
  906.     if(strcmp(argv[3],"slip") == 0)
  907.         mode = SLIP_MODE;
  908. #ifdef    AX25
  909.     else if(strcmp(argv[3],"ax25") == 0)
  910.         mode = AX25_MODE;
  911. #endif
  912. #ifdef    NRS
  913.     else if(strcmp(argv[3],"nrs") == 0)
  914.         mode = NRS_MODE;
  915. #endif
  916. #ifdef    SLFP
  917.     else if(strcmp(argv[3],"slfp") == 0)
  918.         mode = SLFP_MODE;
  919. #endif
  920.     else {
  921.         printf("Mode %s unknown for interface %s\n",
  922.             argv[3],argv[4]);
  923.         return(-1);
  924.     }
  925.  
  926.     dev = nasy++;
  927.  
  928.     /* Create interface structure and fill in details */
  929.     if_asy = (struct interface *)calloc(1,sizeof(struct interface));
  930.     if_asy->name = malloc((unsigned)strlen(argv[4])+1);
  931.     strcpy(if_asy->name,argv[4]);
  932.     if_asy->mtu = atoi(argv[6]);
  933.     if_asy->dev = dev;
  934.     if_asy->recv = doslip;
  935.     if_asy->stop = asy_stop;
  936.  
  937.     switch(mode){
  938. #ifdef    SLIP
  939.     case SLIP_MODE:
  940.         if_asy->ioctl = asy_ioctl;
  941.         if_asy->send = slip_send;
  942.         if_asy->output = NULLFP;    /* ARP isn't used */
  943.         if_asy->raw = slip_raw;
  944.         if_asy->flags = 0;
  945.         slip[dev].recv = slip_recv;
  946.         break;
  947. #endif
  948. #ifdef    AX25
  949.     case AX25_MODE:  /* Set up a SLIP link to use AX.25 */
  950.         axarp();
  951.         if(mycall.call[0] == '\0'){
  952.             printf("set mycall first\n");
  953.             free(if_asy->name);
  954.             free((char *)if_asy);
  955.             nasy--;
  956.             return -1;
  957.         }
  958.         if_asy->ioctl = kiss_ioctl;
  959.         if_asy->send = ax_send;
  960.         if_asy->output = ax_output;
  961.         if_asy->raw = kiss_raw;
  962.         if(if_asy->hwaddr == NULLCHAR)
  963.             if_asy->hwaddr = malloc(sizeof(mycall));
  964.         memcpy(if_asy->hwaddr,(char *)&mycall,sizeof(mycall));
  965.         slip[dev].recv = kiss_recv;
  966.         break;
  967. #endif
  968. #ifdef    NRS
  969.     case NRS_MODE: /* Set up a net/rom serial interface */
  970.         if(argc < 9){
  971.             /* no call supplied? */
  972.             if(mycall.call[0] == '\0'){
  973.                 /* try to use default */
  974.                 printf("set mycall first or specify in attach statement\n");
  975.                 return -1;
  976.             } else
  977.                 addr = mycall;
  978.         } else {
  979.             /* callsign supplied on attach line */
  980.             if(setcall(&addr,argv[8]) == -1){
  981.                 printf ("bad callsign on attach line\n");
  982.                 free(if_asy->name);
  983.                 free((char *)if_asy);
  984.                 nasy--;
  985.                 return -1;
  986.             }
  987.         }
  988.         if_asy->recv = nrs_recv;
  989.         if_asy->ioctl = asy_ioctl;
  990.         if_asy->send = ax_send;
  991.         if_asy->output = ax_output;
  992.         if_asy->raw = nrs_raw;
  993.         if(if_asy->hwaddr == NULLCHAR)
  994.             if_asy->hwaddr = malloc(sizeof(addr));
  995.         memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
  996.         nrs[dev].iface = if_asy;
  997.         break;
  998. #endif
  999. #ifdef    SLFP
  1000.     case SLFP_MODE:
  1001.         if_asy->ioctl = asy_ioctl;
  1002.         if_asy->send = slfp_send;
  1003.         if_asy->recv = doslfp;
  1004.         if_asy->output = NULLFP;    /* ARP isn't used */
  1005.         if_asy->raw = slfp_raw;
  1006.         if_asy->flags = 0;
  1007.         slfp[dev].recv = slfp_recv;
  1008.         break;
  1009. #endif
  1010.     }
  1011.     if_asy->next = ifaces;
  1012.     ifaces = if_asy;
  1013.     asy_init(dev,argv[1],argv[2],(unsigned)atoi(argv[5]));
  1014.     asy_speed(dev,atoi(argv[7]));
  1015. /*
  1016.  * optional SLIP modem command?
  1017.  */
  1018. #if defined(SLIP) && defined(MODEM_CALL)
  1019.     if((mode == SLIP_MODE) && (argc > 8)) {
  1020.         restricted_dev=dev;
  1021.         if((modem_init(dev,argc-8,argv+8)) == -1) {
  1022.         printf("\nModem command sequence failed.\n");
  1023.         asy_stop(if_asy);
  1024.         ifaces = if_asy->next;
  1025.         free(if_asy->name);
  1026.         free((char *)if_asy);
  1027.         nasy--;
  1028.         restricted_dev=1000;
  1029.         return -1;
  1030.         }
  1031.         restricted_dev=1000;
  1032.         return 0;
  1033.     }
  1034. #endif
  1035. #ifdef    SLFP
  1036.     if(mode == SLFP_MODE)
  1037.         if(slfp_init(if_asy, argc>7?argv[8]:NULLCHAR) == -1) {
  1038.         printf("Request for IP address failed.\n");
  1039.         asy_stop(if_asy);
  1040.         ifaces = if_asy->next;
  1041.         free(if_asy->name);
  1042.         free((char *)if_asy);
  1043.         nasy--;
  1044.         return -1;
  1045.         }
  1046. #endif
  1047.     return 0;
  1048. }
  1049. #endif
  1050. #ifndef    NETROM
  1051. #ifdef    AX25
  1052. struct ax25_addr nr_nodebc;
  1053. #endif
  1054. nr_route(bp)
  1055. struct mbuf *bp;
  1056. {
  1057.     free_p(bp);
  1058. }
  1059. nr_nodercv(bp)
  1060. {
  1061.     free_p(bp);
  1062. }
  1063. #endif
  1064.  
  1065.  
  1066. /* Display or set IP interface control flags */
  1067. domode(argc,argv)
  1068. int argc;
  1069. char *argv[];
  1070. {
  1071.     register struct interface *ifp;
  1072.  
  1073.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  1074.         if(strcmp(argv[1],ifp->name) == 0)
  1075.             break;
  1076.     }
  1077.     if(ifp == NULLIF){
  1078.         printf("Interface \"%s\" unknown\n",argv[1]);
  1079.         return 1;
  1080.     }
  1081.     if(argc < 3){
  1082.         printf("%s: %s\n",ifp->name,
  1083.          (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  1084.         return 0;
  1085.     }
  1086.     switch(argv[2][0]){
  1087.     case 'v':
  1088.     case 'c':
  1089.     case 'V':
  1090.     case 'C':
  1091.         ifp->flags = CONNECT_MODE;
  1092.         break;
  1093.     case 'd':
  1094.     case 'D':
  1095.         ifp->flags = DATAGRAM_MODE;
  1096.         break;
  1097.     default:
  1098.         printf("Usage: %s [vc | datagram]\n",argv[0]);
  1099.         return 1;
  1100.     }
  1101.     return 0;
  1102. }
  1103.  
  1104. #ifdef SERVERS
  1105. dostart(argc,argv)
  1106. int argc;
  1107. char *argv[];
  1108. {
  1109.     return subcmd(startcmds,argc,argv);
  1110. }
  1111. dostop(argc,argv)
  1112. int argc;
  1113. char *argv[];
  1114. {
  1115.     return subcmd(stopcmds,argc,argv);
  1116. }
  1117. #endif SERVERS
  1118.  
  1119. #ifdef    TRACE
  1120. static
  1121. int
  1122. dotrace(argc,argv)
  1123. int argc;
  1124. char *argv[];
  1125. {
  1126.         extern int notraceall;  /* trace only in command mode? */
  1127.     struct interface *ifp;
  1128.  
  1129.     if(argc < 2){
  1130.          printf("trace mode is %s\n", (notraceall ? "cmdmode" : "allmode"));
  1131.             printf("trace to %s\n",trfp == stdout? "console" : trname);
  1132.         showtrace(&loopback);
  1133.         for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  1134.             showtrace(ifp);
  1135.         return 0;
  1136.     }
  1137.     if(strcmp("to",argv[1]) == 0){
  1138.         if(argc >= 3){
  1139.             if(trfp != stdout)
  1140.                 fclose(trfp);
  1141.             if(strncmp(argv[2],"con",3) == 0)
  1142.                 trfp = stdout;
  1143.             else {
  1144.                 if((trfp = fopen(argv[2],"a")) == NULLFILE){
  1145.                     printf("%s: cannot open\n",argv[2]);
  1146.                     trfp = stdout;
  1147.                     return 1;
  1148.                 }
  1149.             }
  1150.             strcpy(trname,argv[2]);
  1151.         } else {
  1152.             printf("trace to %s\n",trfp == stdout? "console" : trname);
  1153.         }
  1154.         return 0;
  1155.     }
  1156.     if(strcmp("loopback",argv[1]) == 0)
  1157.         ifp = &loopback;
  1158.      else if (strcmp("cmdmode", argv[1]) == 0) {
  1159.          notraceall = 1;
  1160.          return 0;
  1161.      } else if (strcmp("allmode", argv[1]) == 0) {
  1162.          notraceall = 0;
  1163.          return 0;
  1164.      } else
  1165.         for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  1166.             if(strcmp(ifp->name,argv[1]) == 0)
  1167.                 break;
  1168.  
  1169.     if(ifp == NULLIF){
  1170.         printf("Interface %s unknown\n",argv[1]);
  1171.         return 1;
  1172.     }
  1173.     if(argc >= 3)
  1174.         ifp->trace = htoi(argv[2]);
  1175.  
  1176.     showtrace(ifp);
  1177.     return 0;
  1178. }
  1179. /* Display the trace flags for a particular interface */
  1180. static
  1181. showtrace(ifp)
  1182. register struct interface *ifp;
  1183. {
  1184.     if(ifp == NULLIF)
  1185.         return;
  1186.     printf("%s:",ifp->name);
  1187.     if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT)){
  1188.         if(ifp->trace & IF_TRACE_IN)
  1189.             printf(" input");
  1190.         if(ifp->trace & IF_TRACE_OUT)
  1191.             printf(" output");
  1192.  
  1193.         if(ifp->trace & IF_TRACE_HEX)
  1194.             printf(" (Hex/ASCII dump)");
  1195.         else if(ifp->trace & IF_TRACE_ASCII)
  1196.             printf(" (ASCII dump)");
  1197.         else
  1198.             printf(" (headers only)");
  1199.         printf("\n");
  1200.     } else
  1201.         printf(" tracing off\n");
  1202.     fflush(stdout);
  1203. }
  1204. #endif
  1205.  
  1206. #if    ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
  1207. static
  1208. int
  1209. doescape(argc,argv)
  1210. int argc;
  1211. char *argv[];
  1212. {
  1213.     if(argc < 2)
  1214.         printf("0x%x\n",escape);
  1215.     else 
  1216.         escape = *argv[1];
  1217.     return 0;
  1218. }
  1219. #endif    /* MSDOS */
  1220. static
  1221. doremote(argc,argv)
  1222. int argc;
  1223. char *argv[];
  1224. {
  1225.     struct socket fsock,lsock;
  1226.     struct mbuf *bp;
  1227.  
  1228.     lsock.address = ip_addr;
  1229.     fsock.address = resolve(argv[1]);
  1230.     lsock.port = fsock.port = atoi(argv[2]);
  1231.     bp = alloc_mbuf(1);
  1232.     if(strcmp(argv[3],"reset") == 0){
  1233.         *bp->data = SYS_RESET;
  1234.     } else if(strcmp(argv[3],"exit") == 0){
  1235.         *bp->data = SYS_EXIT;
  1236.     } else {
  1237.         printf("Unknown command %s\n",argv[3]);
  1238.         return 1;
  1239.     }
  1240.     bp->cnt = 1;
  1241.     send_udp(&lsock,&fsock,0,0,bp,0,0,0);
  1242.     return 0;
  1243. }
  1244.